package model

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"time"
	"github.com/go-redis/redis/v8"
)

type Message struct {
	ID         int64     `json:"id"`
	RobotID    string    `json:"robot_id"`
	SocketType int       `json:"socket_type"`
	List       []MsgItem `json:"list"`
	Status     int       `json:"status"`
	ErrorMsg   string    `json:"error_msg"`
	CreateTime time.Time `json:"create_time"`
}

type MsgItem struct {
	Type     int      `json:"type"`
	Content  string   `json:"content"`
	RoomID   string   `json:"room_id"`
	FromUser string   `json:"from_user"`
	ToUser   string   `json:"to_user"`
	AtUsers  []string `json:"at_users"`
	MediaURL string   `json:"media_url"`
}

type MessageModel struct {
	db    *sql.DB
	redis *redis.Client
}

func NewMessageModel(db *sql.DB, redis *redis.Client) *MessageModel {
	return &MessageModel{
		db:    db,
		redis: redis,
	}
}

// 获取当前表名
func (m *MessageModel) getTableName() string {
	timestamp := time.Now().Unix()
	tableIndex := timestamp / (10000000 * 86400)
	return fmt.Sprintf("wqyf_messages_%d", tableIndex)
}

// 验证消息内容是否包含无效的UTF8字符
func isValidUTF8(s string) bool {
	for _, r := range s {
		if r == 0xfffd { // Unicode replacement character
			return false
		}
	}
	return true
}

// 保存消息前验证
func (m *MessageModel) validateMessage(msg *Message) error {
	for _, item := range msg.List {
		// 验证消息内容
		if !isValidUTF8(item.Content) {
			return fmt.Errorf("invalid UTF8 characters in content")
		}
		// 验证发送人
		if !isValidUTF8(item.FromUser) {
			return fmt.Errorf("invalid UTF8 characters in from_user")
		}
		// 验证接收人
		if !isValidUTF8(item.ToUser) {
			return fmt.Errorf("invalid UTF8 characters in to_user")
		}
		// 验证@用户列表
		for _, user := range item.AtUsers {
			if !isValidUTF8(user) {
				return fmt.Errorf("invalid UTF8 characters in at_users")
			}
		}
	}
	return nil
}

// 保存消息
func (m *MessageModel) SaveMessage(ctx context.Context, msg *Message) error {
	// 验证消息内容
	if err := m.validateMessage(msg); err != nil {
		return err
	}

	tableName := m.getTableName()
	
	listJSON, err := json.Marshal(msg.List)
	if err != nil {
		return err
	}

	sql := fmt.Sprintf(`
		INSERT INTO %s (robot_id, socket_type, list, status, create_time)
		VALUES (?, ?, ?, ?, NOW())
	`, tableName)

	result, err := m.db.ExecContext(ctx, sql, msg.RobotID, msg.SocketType, listJSON, msg.Status)
	if err != nil {
		return err
	}

	id, err := result.LastInsertId()
	if err != nil {
		return err
	}
	msg.ID = id

	// 添加缓存
	key := fmt.Sprintf("msg:%d", msg.ID)
	if data, err := json.Marshal(msg); err == nil {
		m.redis.Set(ctx, key, data, 24*time.Hour)
	}

	return nil
}

// 查询消息
func (m *MessageModel) QueryMessages(ctx context.Context, robotID string, startTime, endTime time.Time) ([]*Message, error) {
	tableName := m.getTableName()
	
	query := fmt.Sprintf(`
		SELECT id, robot_id, socket_type, list, status, error_msg, create_time 
		FROM %s 
		WHERE robot_id = ? AND create_time BETWEEN ? AND ?
		ORDER BY create_time DESC LIMIT 1000
	`, tableName)

	rows, err := m.db.QueryContext(ctx, query, robotID, startTime, endTime)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var messages []*Message
	for rows.Next() {
		msg := &Message{}
		var listJSON []byte
		err := rows.Scan(&msg.ID, &msg.RobotID, &msg.SocketType, &listJSON, 
						&msg.Status, &msg.ErrorMsg, &msg.CreateTime)
		if err != nil {
			continue
		}

		if err := json.Unmarshal(listJSON, &msg.List); err != nil {
			continue
		}

		messages = append(messages, msg)
	}

	return messages, nil
}
